/**
 * 
 */
package com.tomagency.cyberlab.client.ui.renderer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.tomagency.cyberlab.client.ClientFactory;
import com.tomagency.cyberlab.client.CssGlobalStyleNames;
import com.tomagency.cyberlab.client.events.BelegEvent;
import com.tomagency.cyberlab.client.events.BelegEventImpl;
import com.tomagency.cyberlab.client.events.ObjectEvent;
import com.tomagency.cyberlab.client.events.ObjectEventImpl;
import com.tomagency.cyberlab.client.events.ObjectEvent;
import com.tomagency.cyberlab.client.events.ObjectEventImpl;
import com.tomagency.cyberlab.client.ui.ObjectListenView.CellRenderer;
import com.tomagency.cyberlab.client.ui.ObjectListenView.RenderType;
import com.tomagency.cyberlab.client.ui.ObjectListenView.RowRenderer;
import com.tomagency.cyberlab.client.ui.ObjectListenView.RowType;

import de.gammadata.gwt.modelle.Adresse;
import de.gammadata.gwt.modelle.Beleg;
import de.gammadata.gwt.modelle.ResultObject;
import de.gammadata.gwt.proxy.*;


import com.tomagency.cyberlab.client.ui.ObjectListenView.ObjectEventHandler;

/**
 * @author gfr
 *
 */
public class BelegRowRendererImpl implements RowRenderer<ObjectEvent>{
	
//	public static int MAX_SUBJECT_LENGTH=57;
//	public static String MORE_STRING=" ...";
//	
//	DateTimeFormat dateFormat = DateTimeFormat.getFormat("dd.MM.yy");
//	DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("dd.MM.yy HH:mm");
//	NumberFormat numFormat = NumberFormat.getFormat("#########0.00");
	
	List<CellRenderer<ObjectEvent>> cellRendererList;	
	List<CellRenderer<ObjectEvent>> fullCellRendererList;
	
	public BelegRowRendererImpl(){
		bind();
	}
	
	private void bind(){
		cellRendererList = new ArrayList<CellRenderer<ObjectEvent>>();
		cellRendererList.add(new BelegStatusRenderer());
		cellRendererList.add(new BelegNummerRenderer());
		cellRendererList.add(new BelegDatumRenderer());
		cellRendererList.add(new TotalPreisRenderer());
		cellRendererList.add(new SubjectRenderer());
		
		fullCellRendererList = new ArrayList<CellRenderer<ObjectEvent>>();
		fullCellRendererList.add(new BelegStatusRenderer()); // 
		fullCellRendererList.add(new FullBelegInfoRenderer());
		fullCellRendererList.add(new CollapseCellRenderer());
//		CellRenderer nullRenderer = new NullRenderer();
//		fullCellRendererList.add(nullRenderer);
//		fullCellRendererList.add(nullRenderer);
//		fullCellRendererList.add(nullRenderer);

		
	}

	@Override
	public List<CellRenderer<ObjectEvent>> getCellRendererList(
			RenderType renderType) {
		if (renderType.compareTo(RenderType.FULL)==0)
			return fullCellRendererList;
		
		return cellRendererList;
	}
	
	class NullRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {

			return 0;
		}

		@Override
		public Widget getColumnWidget(RowType rowType,
				ObjectEventHandler handler, Object dataObj) {
			// TODO Auto-generated method stub
			return null;
		}
		
	}
	
	class BelegStatusRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {
			return 1;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegListProxy beleg = Util.getBelegListProxy(dataObj);
			String status=beleg.getStatus();
			
			

			HTML label =new HTML("&nbsp;");
			if (status.equalsIgnoreCase(Beleg.STATUS_NEU)
					||status.equalsIgnoreCase(Beleg.STATUS_INKATIV)
					||status.equalsIgnoreCase(Beleg.STATUS_WARTET)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_NEU);
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_BESTELLT)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_BESTELLT);
				
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_INARBEIT)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_INARBEIT);
				
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_PRODUZIERT)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_PRODUZIERT);
				
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_FERTIG)
					||status.equalsIgnoreCase(Beleg.STATUS_REINKOMMEND)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_PRODUZIERT);
				
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_ACHTUNG)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_ACHTUNG);
				
			}
			else if(status.equalsIgnoreCase(Beleg.STATUS_STORNO)){
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_STORNO);
				
			}
			else{
				label.setStyleName(CssGlobalStyleNames.AUFTRAG_ABGESCHLOSSEN);
				
			}
			
			return label;
			
			
		}
		
	}
	
	class BelegNummerRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {
			return 1;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegListProxy beleg = Util.getBelegListProxy(dataObj);
			int belegNummer=beleg.getNummer();
			Label num = new Label(Integer.toString(belegNummer));
			return num;
		}
		
	}
	
	class BelegDatumRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {
			return 1;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegListProxy beleg = Util.getBelegListProxy(dataObj);
			Label datum = new Label(ClientFactory.dateFormat.format(beleg.getDatum()));
			datum.addStyleName(CssGlobalStyleNames.LISTE_DATUM);
			return datum;
		}
		
	}
	
	class TotalPreisRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {
			return 1;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegListProxy beleg = Util.getBelegListProxy(dataObj);
			Label total=new Label(beleg.getTotalString());
			return total;
		}
		
	}
	
	class SubjectRenderer implements CellRenderer<ObjectEvent>{
		


		@Override
		public int getColSpan() {
			return 1;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegListProxy beleg = Util.getBelegListProxy(dataObj);
			Label subject;
			if (beleg.getSubject()!=null && beleg.getSubject().length()>ClientFactory.MAX_SUBJECT_LENGTH)
				subject=new Label(beleg.getSubject().substring(0, ClientFactory.MAX_SUBJECT_LENGTH)+ClientFactory.MORE_STRING);
			else
				subject=new Label(beleg.getSubject());
			return subject;
		}
		
	}
	
	class FullBelegInfoRenderer implements CellRenderer<ObjectEvent>{

		@Override
		public int getColSpan() {
			return 4;
		}

		@Override
		public Widget getColumnWidget(
				RowType rowType, ObjectEventHandler handler,
				Object dataObj) {
			BelegViewProxy beleg = (BelegViewProxy)dataObj;
			
			HTML innerHtml = new HTML();
			
			String posliste;
			if (beleg.getPositionsListe()!=null&&beleg.getPositionsListe().size()>0){
				
				StringBuilder pl = new StringBuilder();
				int posNr=0;
				for (BelegPositionListProxy pos : beleg.getPositionsListe()){
					if (posNr>0)
						pl.append("<br/>");  //Ab 2. Pos ein Zwischenraum
					pl.append(
							"<br/>"
							+"Pos "+pos.getPosNummer()+ ": "+pos.getBezeichnung()+ ", "+ClientFactory.numFormat.format(pos.getMenge())+" Stk"
							+"<br/>"+pos.getBeschreibung().replace("\n", "<br/>"));
					posNr++;
				}
				posliste = pl.toString();
			}
			else{
				posliste = "---- keine Positionen vorhanden ---- ";
			}
			StringBuilder msgListe = new StringBuilder();
			if(beleg.getMessageListe()!=null&&beleg.getMessageListe().size()>0){
				msgListe.append("<p class=\""+CssGlobalStyleNames.EINTRAG_MSGLISTE+"\">");
				boolean notFirst=false;
				for (MessageListProxy msg: beleg.getMessageListe()){
					if (notFirst)
						msgListe.append("<br/>");
					msgListe.append(ClientFactory.dateTimeFormat.format(msg.getDate())+": "+msg.getSubject());
					notFirst=true;
				}
				msgListe.append("</p>");
				
			}
			if (beleg.getAdresse()!=null&&
					beleg.getAdresse().getNutzung()!=null&&
					Adresse.Nutzung.FIRMA.compareTo(beleg.getAdresse().getNutzung())==0){
				
			}
			String kommAdrTxt = beleg.getEmailAdresse().getNameNummer();
			if (beleg.getKontakt().getKommAdressenListe()!=null&&beleg.getKontakt().getKommAdressenListe().size()>0){
				for (KommAdresseListProxy komAdr:beleg.getKontakt().getKommAdressenListe()){
					kommAdrTxt+="<br/>"+komAdr.getNameNummer();
				}
			}

			innerHtml.setHTML(
					"<p>"
					+"<b>"+beleg.getNummer()
					+", "+ClientFactory.dateTimeFormat.format(beleg.getDatum())
					+ " , "+beleg.getVersandArt().getBeschreibung()
					+ " , "+beleg.getZahlungsBedingung().getBeschreibung()
					+ ", "+beleg.getTotalString()
					+ "</b> "
					+"<br/>"
					+"<table>"
					+"<tr>"
					+"<td>"
					+beleg.getKontakt().getNamenString()
					+"<br/>"
					+beleg.getAdresse().getStandardAdressString().replace("\n", "<br/>")
					+"</td>"
					+"<td style=\"width:30px;\">"
					+"</td>"
					+"<td>"
					+ kommAdrTxt
					+"</td>"
					+"</tr>"
					+"</table>"
					+"<br/>"
					+beleg.getSubject()
					+"<br/>"
					+posliste
					+"</p>"
					+msgListe);
			
			HTMLPanel panel = new HTMLPanel("");
			panel.setStyleName(CssGlobalStyleNames.EINTRAG_FULL);
			innerHtml.setStyleName(CssGlobalStyleNames.EINTRAG_FULL);
			panel.add(innerHtml);
			HorizontalPanel hp = new HorizontalPanel();
			
			Label label= new Label();
			label.setStyleName(CssGlobalStyleNames.EINTRAG_MSG);
			
			ListBox statusBox = new ListBox();
			statusBox.addStyleName(CssGlobalStyleNames.EINTRAG_STATUS_BOX);
			StatusBoxChangeHandler boxHdl = new StatusBoxChangeHandler(beleg.getId(), statusBox, label,handler);
			statusBox.addChangeHandler(boxHdl);
			statusBox.addClickHandler(boxHdl);
			
			statusBox.addItem(Beleg.STATUS_NEU);
			statusBox.addItem(Beleg.STATUS_INKATIV);
			statusBox.addItem(Beleg.STATUS_BESTELLT);
			statusBox.addItem(Beleg.STATUS_WARTET);
			statusBox.addItem(Beleg.STATUS_INARBEIT);				
			statusBox.addItem(Beleg.STATUS_PRODUZIERT);
			statusBox.addItem(Beleg.STATUS_FERTIG);
			statusBox.addItem(Beleg.STATUS_REINKOMMEND);
			statusBox.addItem(Beleg.STATUS_ABGESCHLOSSEN);				
			statusBox.addItem(Beleg.STATUS_STORNO);
			statusBox.addItem(Beleg.STATUS_ACHTUNG);
			
			for (int i=0;i<statusBox.getItemCount();i++){
				if (statusBox.getItemText(i).equalsIgnoreCase(beleg.getStatus())){
					statusBox.setSelectedIndex(i);
				}
			}

			Label statusLabel = new Label("Status: ");
			statusLabel.addStyleName(CssGlobalStyleNames.EINTRAG_STATUS);
			hp.add(statusLabel);
			hp.add(statusBox);
			
			if (Beleg.STATUS_NEU.equalsIgnoreCase(beleg.getStatus())
					|| Beleg.STATUS_INKATIV.equalsIgnoreCase(beleg.getStatus())
					||Beleg.STATUS_WARTET.equalsIgnoreCase(beleg.getStatus())){
			Button bubuButton = new Button();
			bubuButton.addStyleName(CssGlobalStyleNames.EINTRAG_BUTTON);
			bubuButton.setText("erzeuge Bestellung");
			hp.add(bubuButton);
			
			bubuButton.addClickHandler(new BubuClickHandler(beleg.getId(),label,handler));				
			
			}
			hp.add(label);
			
			
			panel.add(hp);
			return panel;
		}
		
	}
	
	private class StatusBoxChangeHandler implements ChangeHandler, ClickHandler{
		
		private Integer id;
		private Label label;
		private ListBox statusBox;
		private ObjectEventHandler handler;
		
		StatusBoxChangeHandler(Integer id,ListBox statusBox,Label label,ObjectEventHandler handler){
			this.id=id;
			this.label=label;
			this.statusBox=statusBox;
			this.handler=handler;
		}

		@Override
		public void onChange(ChangeEvent event) {
			// TODO Auto-generated method stub
			event.stopPropagation();
			String neuerStatus= statusBox.getItemText(statusBox.getSelectedIndex());
			StatusBoxChangeHandler.this.label.setStyleName(CssGlobalStyleNames.EINTRAG_MSG);
			StatusBoxChangeHandler.this.label.setText("setze Status: "+neuerStatus);
			/*
			 * Object Handling ist an den Persenter.Objecthandler delegiert
			 */
			BelegEvent oe = new BelegEventImpl();
			oe.setEventType(ObjectEvent.ONSETPROPERTIES);
			oe.setObjectId(id);
			Map<String,String> props = new HashMap<String,String>();
			props.put("status", neuerStatus);
			oe.setProperties(props);
			oe.setMessageWidget(label);
			handler.onObjectEvent(oe);
			
			
			 
		}
		@Override
		public void onClick(ClickEvent event) {
			event.stopPropagation();
			
		}
		
	}
	
	private class BubuClickHandler implements ClickHandler{
		
		private Integer id;
		private Label label;
		private ObjectEventHandler handler;

		BubuClickHandler(Integer id, Label label,ObjectEventHandler handler){
			
			this.id=id;
			this.label=label;
			this.handler=handler;
			
		}

		@Override
		public void onClick(ClickEvent event) {
			BubuClickHandler.this.label.setStyleName(CssGlobalStyleNames.EINTRAG_MSG);
			BubuClickHandler.this.label.setText("erzeuge Bestellung ....");
			event.stopPropagation();
			
			/*
			 * Object Handling ist an den Persenter.Objecthandler delegiert
			 */
			BelegEvent oe = new BelegEventImpl();
			oe.setEventType(BelegEvent.ONINVOKE_FUNCTION);
			oe.setFunctionCode(BelegEvent.FUNCTION_GEN_BUBU_XML);
			oe.setObjectId(id);
			oe.setMessageWidget(label);
			handler.onObjectEvent(oe);
			
//			BubuClickHandler.this.label.setText();
//			serviceProvider.getBelegService().placeBuBuOrder(id, new AsyncCallback<ResultObject>(){
//				@Override
//				public void onFailure(Throwable e) {
//					BubuClickHandler.this.label.setStyleName(CssGlobalStyleNames.EINTRAG_ERROR);
//					BubuClickHandler.this.label.setText("  Fehler"+e.getMessage());
//					
//				}
//
//				@Override
//				public void onSuccess(ResultObject result) {
//					BubuClickHandler.this.label.setText("  "+result.getMessage());
//				}
//				
//			});
//			
		}		
	}
	
	private static class Util{
		
		static BelegListProxy getBelegListProxy(Object dataObj){
			
			BelegListProxy obj=obj = (BelegListProxy)dataObj;

			return obj;
			
		}
		
	}
}
